package xiangya.bysj.service.impl;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import xiangya.bysj.entity.HistoryTake;
import xiangya.bysj.entity.HistoryTakeCache;
import xiangya.bysj.entity.Patient;
import xiangya.bysj.entity.TakeCycle;
import xiangya.bysj.entity.TakeInfo;
import xiangya.bysj.mapper.interf.HistoryTakeMapper;
import xiangya.bysj.mapper.interf.PatientMapper;
import xiangya.bysj.mapper.interf.TakeInfoMapper;
import xiangya.bysj.service.interf.HistoryTakeServiceInterface;
import xiangya.bysj.util.JsonUtil;
import xiangya.bysj.util.StringUtil;

@Service("historyTakeService") // 注册业务类
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class) // 注明需要回滚
public class HistoryTakeServiceImpl implements HistoryTakeServiceInterface {

	@Autowired
	private HistoryTakeMapper historyTakeMapper;

	@Autowired
	private TakeInfoMapper takeInfoMapper;

	@Autowired
	private PatientMapper patientMapper;

	@Override
	public void save(HistoryTake obj) throws Exception {
		historyTakeMapper.save(obj);
	}

	@Override
	public void update(HistoryTake obj) throws Exception {
		historyTakeMapper.update(obj);
	}

	@Override
	public void delete(int objId) throws Exception {
		historyTakeMapper.delete(objId);
	}

	@Override
	public List<HistoryTake> getByPage(int currentPage, int pageNum, int userId) throws Exception {
		int from = currentPage * (pageNum - 1);
		List<Patient> list = patientMapper.findPatientsByUser(userId);
		int[] ptIds = new int[list.size()];
		for (int i = 0; i < ptIds.length; i++) {
			ptIds[i] = list.get(i).getId();
		}
		return historyTakeMapper.selectByPage(from, pageNum, ptIds);
	}

	@Scheduled(cron = "0 0 0 * * ?")
	@Override
	public void produceBatch() throws Exception {
		int current = 1;
		int number = 20;
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Date date = new Date();
		String nowDate = df.format(date);
		List<HistoryTake> htList = new ArrayList<HistoryTake>();
		List<HistoryTakeCache> caList;
		HistoryTake history;
		Map<String, Integer> map;
		while ((caList = takeInfoMapper.selectByNowDate(nowDate, (current - 1) * number, number)) != null
				&& caList.size() > 0) {
			for (HistoryTakeCache hca : caList) {
				map = (Map<String, Integer>) JsonUtil.getObject(hca.getTakeTimeNum(), Map.class);
				for (Map.Entry<String, Integer> entry : map.entrySet()) {
					history = new HistoryTake();
					history.setHistDate(nowDate);
					history.setHistNum(entry.getValue());
					history.setHistTime(entry.getKey());
					history.setMedicId(hca.getMedicId());
					history.setMedicName(hca.getMedicName());
					history.setPatientId(hca.getPatientId());
					history.setPatientName(hca.getPatientName());
					history.setTkId(hca.getTkId());
					htList.add(history);
				}
			}
			current++;
		}
		historyTakeMapper.saveBatch(htList);
	}

	@Override
	public List<HistoryTake> getTodayRecByPatientId(int patientId, String today) throws Exception {
		return historyTakeMapper.selectTodayRecByPatientId(patientId, today);
	}

	@Override
	public List<HistoryTake> getByUser(int userId) throws Exception {
		List<Patient> list = patientMapper.findPatientsByUser(userId);
		int[] ptIds = new int[list.size()];
		for (int i = 0; i < ptIds.length; i++) {
			ptIds[i] = list.get(i).getId();
		}
		if (ptIds.length > 0) {
			SimpleDateFormat sdf = new SimpleDateFormat(StringUtil.DATE_FORMAT);
			return historyTakeMapper.selectByPatients(ptIds, sdf.format(new Date()));
		} else {
			return new ArrayList<HistoryTake>();
		}
	}

	@Override
	public List<HistoryTake> getByPatients(List<Patient> patients, boolean isToday) throws Exception {
		int[] ptIds = new int[patients.size()];
		for (int i = 0; i < ptIds.length; i++) {
			ptIds[i] = patients.get(i).getId();
		}
		if (ptIds.length > 0) {
			if (isToday == true) {
				SimpleDateFormat sdf = new SimpleDateFormat(StringUtil.DATE_FORMAT);
				return historyTakeMapper.selectByPatients(ptIds, sdf.format(new Date()));
			} else {
				return historyTakeMapper.selectAllByPatients(ptIds);
			}
		}
		return new ArrayList<HistoryTake>();
	}

	@Override
	public boolean deleteByPatient(int patientId, int medicId) throws Exception {
		boolean result = false;
		if (historyTakeMapper.deleteByPatient(patientId, medicId) > 0) {
			result = true;
		}
		return result;
	}

	@Override
	public int getNumberByPatient(int patientId, int medicId) throws Exception {
		return historyTakeMapper.selectNumberByPatient(patientId, medicId);
	}

	@Override
	public List<HistoryTake> getByPatient(int patientId, int medicId) throws Exception {
		return historyTakeMapper.selectByPatient(patientId, medicId);
	}

	@Override
	public boolean updateRecord(int patientId, int medicId, String record, String date) throws Exception {
		boolean result = false;
		if (historyTakeMapper.updateRecord(patientId, medicId, record, date) > 0) {
			result = true;
		}
		return result;
	}
	
	public int getHistCountByPatient(int patientid){
		return historyTakeMapper.selectHistCountByPatient(patientid);
	};
	
	

	@Override
	public int createHistBatch(List<TakeInfo> caList) throws Exception {

		if (caList != null && caList.size() > 0) {
			List<HistoryTake> historys = new ArrayList<HistoryTake>();
			SimpleDateFormat format = new SimpleDateFormat(StringUtil.DATE_FORMAT);
			Date today = format.parse(format.format(new Date()));
			Date start = null;
			Date end = null;
			HistoryTake history = null;
			Map<String, Integer> map = null;
			for (TakeInfo takeinfo : caList) {
				for (TakeCycle cycle : takeinfo.getTkCycle()) {
					start = format.parse(cycle.getCycleStart());
					end = format.parse(cycle.getCycleEnd());
					if ((today.before(end) && today.after(start)) || today.equals(end) || today.equals(start)) {
						map = (Map<String, Integer>) JsonUtil.getObject(cycle.getTkTiNum(), LinkedHashMap.class);
						for (Map.Entry<String, Integer> entry : map.entrySet()) {
							history = new HistoryTake();
							history.setHistDate(format.format(today));
							history.setHistNum(entry.getValue());
							history.setHistTime(entry.getKey());
							history.setMedicId(takeinfo.getMedicId());
							history.setMedicName(takeinfo.getMedicName());
							history.setPatientId(takeinfo.getPatientId());
							history.setPatientName(takeinfo.getPatientName());
							history.setTkId(takeinfo.getTkId());
							historys.add(history);
						}
					}
				}
			}
			return historyTakeMapper.saveBatch(historys);
		}
		return 0;
	}

	@Override
	public int deleteTodayByTk(int tkId) throws Exception {
		SimpleDateFormat formate = new SimpleDateFormat(StringUtil.DATE_FORMAT);
		String today = formate.format(new Date());
		return historyTakeMapper.deleteTodayByTk(tkId, today);
	}

	@Override
	public List<HistoryTake> getAlert(int userId, boolean isAlert, String time) throws Exception {
		List<Patient> list = patientMapper.findPatientsByUser(userId);
		List<HistoryTake> historys = null;
		if (list != null) {
			SimpleDateFormat format = new SimpleDateFormat(StringUtil.DATE_FORMAT);
			int[] ptIds = new int[list.size()];
			for (int i = 0; i < ptIds.length; i++) {
				ptIds[i] = list.get(i).getId();
			}
			List<HistoryTake> his = historyTakeMapper.selectByPatients(ptIds, format.format(new Date()));
			if (his != null && his.size() > 0) {
				format = new SimpleDateFormat(StringUtil.DATE_FORMAT + " " + StringUtil.HOUR_FOMAT);
				long[] hTimes = new long[his.size()];
				for (int i = 0; i < his.size(); i++) {
					HistoryTake h = his.get(i);
					long t = format.parse(h.getHistDate() + " " + h.getHistTime()).getTime();
					hTimes[i] = t;
				}
				Arrays.sort(hTimes);
				long now = format.parse(time).getTime();
				long choTime = 0;
				historys = new ArrayList<HistoryTake>();
				// 客户端正在提醒中，查找下一次的
				if (isAlert == true) {
					for (int i = 0; i < hTimes.length; i++) {
						if (now < hTimes[i]) {
							choTime = hTimes[i];
							break;
						}
					}
				} else { // 没有提醒，先查找时间相同的，没有则找时间比较大的
					for (int i = 0; i < hTimes.length; i++) {
						if (now <= hTimes[i]) {
							choTime = hTimes[i];
							break;
						}
					}
				}
				if (choTime > 0) {
					for (HistoryTake h : his) {
						long t = format.parse(h.getHistDate() + " " + h.getHistTime()).getTime();
						if (t == choTime) {
							historys.add(h);
						}
					}
				}
			}

		}
		return historys;
	}

	public List<HistoryTake> getByPatientId(int offset,int patientid) {
		// TODO Auto-generated method stub
		return historyTakeMapper.selectByPatientId(patientid,offset);
	}

}
